package com.wyh.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bite.blog.api.BlogServiceApi;
import com.bite.blog.api.pojo.BlogInfoResponse;
import com.bite.common.exception.BlogException;
import com.bite.common.pojo.Result;
import com.bite.common.utils.*;
import com.bite.user.api.pojo.UserInfoRegisterRequest;
import com.bite.user.api.pojo.UserInfoRequest;
import com.bite.user.api.pojo.UserInfoResponse;
import com.bite.user.api.pojo.UserLoginResponse;
import com.wyh.user.constant.Constant;
import com.wyh.user.covert.BeanCovert;
import com.wyh.user.dataobject.UserInfo;
import com.wyh.user.mapper.UserInfoMapper;
import com.wyh.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private BlogServiceApi blogServiceApi;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    RabbitTemplate rabbitTemplate;

    private static final long REDIS_EXPIRATION_TIME = 14*24*60*60;
//    private static final String PREFIX = "";

    @Override
    public UserLoginResponse login(UserInfoRequest user) {
        //验证账号密码是否正确
        UserInfo userInfo = queryUserInfo(user.getUserName());
        if (userInfo==null || userInfo.getId()==null){
            throw new BlogException("用户不存在");
        }
//        if (!user.getPassword().equals(userInfo.getPassword())){
//            throw new BlogException("用户密码不正确");
//        }
        if (!SecurityUtil.verify(user.getPassword(),userInfo.getPassword())){
            throw new BlogException("用户密码不正确");
        }
        //账号密码正确的逻辑
        Map<String,Object> claims = new HashMap<>();
        claims.put("id", userInfo.getId());
        claims.put("name", userInfo.getUserName());

        String jwt = JWTUtils.genJwt(claims);
        return new UserLoginResponse(userInfo.getId(), jwt);
    }

    private UserInfo queryUserInfo(String userName) {
        //先从redis中查找
        String key = buildKey("user", userName);
        if (redisUtils.contains(key)){
            UserInfo userInfo = JsonUtil.toObject(redisUtils.get(key), UserInfo.class);
            return userInfo==null?selectUserInfoByName(userName):userInfo;
        }else {
            //找不到去mysql
            UserInfo userInfo = selectUserInfoByName(userName);
            redisUtils.set(key,JsonUtil.toJsonString(userInfo),REDIS_EXPIRATION_TIME);
            return userInfo;
        }
    }

    @Override
    public UserInfoResponse getUserInfo(Integer userId) {
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        UserInfo userInfo = selectUserInfoById(userId);
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    @Override
    public UserInfoResponse selectAuthorInfoByBlogId(Integer blogId) {
        UserInfoResponse userInfoResponse = new UserInfoResponse();

        //远程调用
        //1. 根据博客ID, 获取作者ID
        Result<BlogInfoResponse> blogDeatail = blogServiceApi.getBlogDeatail(blogId);
        //2. 根据作者ID, 获取作者信息
        if (blogDeatail == null || blogDeatail.getData() == null){
            throw new BlogException("博客不存在");
        }
        UserInfo userInfo = selectUserInfoById(blogDeatail.getData().getUserId());
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    @Override
    public Integer register(UserInfoRegisterRequest request) {
        //检查请求是否合法
        checkRegisterRequest(request);
        //插入数据库
        UserInfo userInfo = BeanCovert.covertToUserInfo(request);
        try {
            int insert = userInfoMapper.insert(userInfo);
            if (insert != 1){
                throw new BlogException("注册失败");
            }else {
                redisUtils.set(buildKey("user", userInfo.getUserName()), JsonUtil.toJsonString(userInfo), REDIS_EXPIRATION_TIME);
                rabbitTemplate.convertAndSend(Constant.USER_EXCHANGE,Constant.USER_BINDING_KEY,JsonUtil.toJsonString(userInfo));
                return userInfo.getId();
            }
        }catch (Exception e){
            throw new BlogException("注册失败！");
        }
    }

    private String buildKey(String prefix, String... strings) {
        return redisUtils.keyBuilder(prefix,strings);
    }

    private void checkRegisterRequest(UserInfoRegisterRequest request) {
        UserInfo userInfo = userInfoMapper.selectByName(request.getUserName());
        if (userInfo != null) {
            log.error("user:{}", request.getUserName());
            throw new BlogException("用户已存在！");
        }

        if (!RegexUtil.checkMail(request.getEmail())){
            log.error("email:{}", request.getEmail());
            throw new BlogException("邮箱不合法！");
        }

        if (!RegexUtil.checkURL(request.getGithubUrl())){
            log.error("github:{}", request.getGithubUrl());
            throw new BlogException("github地址不合法！");
        }
    }

    public UserInfo selectUserInfoByName(String userName) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getUserName, userName).eq(UserInfo::getDeleteFlag, 0));
    }
    private UserInfo selectUserInfoById(Integer userId) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getId, userId).eq(UserInfo::getDeleteFlag, 0));
    }

//    private BlogInfo getBlogInfo(Integer blogId) {
//        return blogMapper.selectOne(new LambdaQueryWrapper<BlogInfo>()
//                .eq(BlogInfo::getDeleteFlag, 0).eq(BlogInfo::getId, blogId));
//    }
}
